#include "mythread.h"
#include "rsa.h"
#include "format.h"
#include <strings.h>
#include <QByteArray>

//static struct User{
//    char m_name[64];
//    char m_passwd[64];
//    u_int32_t   m_position;
//    int64_t     m_timestamp;
//    u_int8_t    m_isStudy;
//}user ={
//    "dy","psddy", 0,1,0,
//};

mythread::mythread()
{
    client = new QTcpSocket(this);
    connectServer();
}

mythread::mythread(QString name, QString passwd)
{
    m_name = name;
    m_passwd = passwd;
    client = new QTcpSocket(this);
    connectServer();
}

void mythread::run()
{

}


void mythread::connectServer()
{
    client->connectToHost("139.199.172.253",10086);

    //如果套接字发出信号connected(),说明连接服务器成功
    connect(client,SIGNAL(connected()),this,SLOT(onConected()));

    //如果连接出错，发出信号error()
    connect(client,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(onError()));

    //如果有数据可读，发出信号readyRead()
    connect(client,SIGNAL(readyRead()),this,SLOT(onReadData()));
}

int mythread::saveTimestamp(void *buf, quint32 packet_len)
{
    //printf("packet_len = %d\n",packet_len);
    decodeTimestamp(buf,packet_len,&m_position,&m_timestamp);
    //printf("position:%d,time:%s\n",user.m_position,ctime((time_t *)&user.m_timestamp));
    //qDebug()<<"m_timestamp:"<<m_timestamp;
    if(m_timestamp >0){
        QDateTime recv_time = QDateTime::fromTime_t(m_timestamp);
        //qDebug()<<"time:"<<recv_time;
    }
    emit sigStudyStatuschanged(m_timestamp);
    return 0;
}

int mythread::delClientRecv(quint16 cmd, quint32 packet_len, char *buf)
{
    signed int err = 0;
    //char send_cmd[MAX_MESSAGE_SIZE];
    //printf("cmd num = %d\n",cmd);
    switch (cmd){
        case e_msgDebug:
            printf("recv: %s",buf);
            break;
        case e_msgTimestamp:
             //保存时间戳
             //printf("receive timestamp\n");
             err = saveTimestamp(buf,packet_len);
             break;
        default:
            qDebug()<<"unknow cmd\n";
            return -1;
    }
    if(err){
        // head_package(send_cmd,err,0);
        // bufferevent_write(bev, send_cmd, Msg.m_msgLen);
        qDebug()<<"error ??\n";
    }
    return 0;
}

void mythread::onConected()
{
    qDebug("connect server ok!");
    //client->write("");
    client_login();
    timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()),this,SLOT(onTimeout()));
    timer->setInterval(5000);//定时5000毫秒
    timer->start();
}

void mythread::onError()
{
    qDebug() << "error1: " << client->error();
    qDebug() << "error2: " << client->errorString();
}

void mythread::onReadData()
{
    qDebug()<<"*****************\n";
    char buf[MAX_MESSAGE_SIZE];
    memset(buf,0,MAX_MESSAGE_SIZE);
    int count=0;

    count = client->read(buf,Msg.m_msgLen);
    /* 1.对端发送FIN后，还向这个套接字写会收到 RST */
    if ( count < 0) {
        perror("read sockfd");
        client->close();  //关掉这个套接字
        return ;
    }
    /* 2.对方发送了FIN,服务器读会返回0，应答后处于CLOSE_WAIT状态 */
    else if (count == 0){
        printf("\ra user closed  \n");
        client->close();  //关掉这个套接字
        return ;
    }
    /* 3.没有读到6个字节 */
    else if(count < 6){
        printf("messages is less than 6\n");
        client->close();  //关掉这个套接字
        return ;
    }

    /* 4.正常读数据 */
    unsigned short cmd_num = 0;
    unsigned int packet_len = 0;
    head_analyze(buf,&cmd_num,&packet_len);
    count = client->read(buf, packet_len);
    if(count < packet_len){
        //qDebug()"cmd_num = %d,count = %d\n,packet_len = %d\n"<<cmd_num,count,packet_len;
        qDebug()<<"read failed!??\n";
        return ;
    }
    //处理加密后的时间戳
    delClientRecv(cmd_num,packet_len,buf);
    return ;
}

int mythread::client_login()
{
    char buf[MAX_MESSAGE_SIZE];
    char name_passwd[MAX_MESSAGE_SIZE];

    /* 1.按格式填写姓名密码字段 */
    QByteArray name = m_name.toLatin1();
    QByteArray passwd = m_passwd.toLatin1();
    int len = snprintf(name_passwd,MAX_MESSAGE_SIZE,"$%s;%s;pc;\n",name.data(),passwd.data());
    len = len+key.m_public.m_bytes-len%key.m_public.m_bytes;

    /* 2.对登陆信息进行加密 */
    int *encode = encodeMessage(len, key.m_public.m_bytes, name_passwd,
            key.m_public.m_exponent, key.m_public.m_modulus);
    int encode_len = len/key.m_public.m_bytes*sizeof(int);

    /* 3.构造数据包 */
    memcpy(buf+Msg.m_msgLen, encode, encode_len);
    head_package(buf,e_msgLogin,encode_len);
    client->write(buf,Msg.m_msgLen+encode_len);
    //qDebug()<<"Msg.m_msgLen+encode_len:"<<Msg.m_msgLen+encode_len;
    free(encode);
    return 0;
}

/**
 * @brief mythread::onTimeout
 *      保活，服务器收到消息会返回时间戳
 */
void mythread::onTimeout()
{
    /* 加密时间戳，虽然服务器不会用到PC端发送的时间戳 */
    char send_cmd[128];
    int len = encodeTimestamp(send_cmd+6,m_position,m_timestamp);
    head_package(send_cmd,e_msgBegTimestamp,len);
    client->write(send_cmd,Msg.m_msgLen+len);
    timer->setInterval(5000);//定时5000毫秒
    timer->start();

}


